# -*- coding: utf-8 -*- 
"""
Project: AppleSnApi
Creator: SF
Create time: 2025-06-16 11:51
IDE: PyCharm
Introduction: 工具函数
"""
import ddddocr
import base64
import re
import os
import sys
import socket
import psutil
import platform
from datetime import datetime

current_path = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(current_path)[0]
sys.path.append(rootPath)


def ddddOcr2captcha(b64_img):
    """
    :param b64_img:
    :param ocr_type:
    :return: 使用开源库ddddocr 识别验证码
    """
    ocr = ddddocr.DdddOcr(show_ad=False)
    data = base64.b64decode(b64_img)
    captcha = ocr.classification(data)
    return captcha


def validate_sn_code(sn_code: str):
    """验证SN码格式"""
    # 长度验证
    if not sn_code or not sn_code.strip():
        raise ValueError("SN码不能为空")

    if not (10 <= len(sn_code) <= 14):
        raise ValueError("SN码长度必须在10-14位之间")

    # 格式验证（仅允许英文字母+数字）
    if not re.match(r'^[a-zA-Z0-9]+$', sn_code):
        raise ValueError("SN码只能包含英文字母和数字")
    return sn_code


def get_system_info(target_process="worker.py"):
    """
    获取当前主机的关键系统信息（简化版）

    返回:
        dict: 包含关键系统信息的字典
    """
    try:
        # 基本信息
        system_info = {
            "hostname": socket.gethostname(),
            "os": platform.system(),
            "os_version": f"{platform.version()} {platform.release()}",
            "python_version": platform.python_version(),
            "current_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "uptime": get_system_uptime(),
        }

        # CPU信息
        cpu_info = {
            "count_logical": psutil.cpu_count(logical=True),
            "count_physical": psutil.cpu_count(logical=False),
            "usage_percent": psutil.cpu_percent(interval=1),  # 1秒内的CPU使用率
            "usage_percent_per_cpu": psutil.cpu_percent(interval=1, percpu=True),  # 每个CPU核心的使用率
            "freq_current": psutil.cpu_freq().current,  # 当前频率
            "freq_min": psutil.cpu_freq().min,  # 最小频率
            "freq_max": psutil.cpu_freq().max,  # 最大频率
            "core_count": psutil.cpu_count(logical=True),
        }
        system_info["cpu"] = cpu_info

        # 内存信息
        virtual_memory = psutil.virtual_memory()
        swap_memory = psutil.swap_memory()

        memory_info = {
            "total": format_bytes(virtual_memory.total),
            "available": format_bytes(virtual_memory.available),
            "used": format_bytes(virtual_memory.used),
            "free": format_bytes(virtual_memory.free),
            "usage_percent": virtual_memory.percent,
            "swap_total": format_bytes(swap_memory.total),
            "swap_used": format_bytes(swap_memory.used),
            "swap_free": format_bytes(swap_memory.free),
            "swap_usage_percent": swap_memory.percent,
        }
        system_info["memory"] = memory_info

        # 磁盘信息（根目录）
        try:
            disk_usage = psutil.disk_usage('/')
            disk_info = {
                "total": format_bytes(disk_usage.total),
                "used": format_bytes(disk_usage.used),
                "free": format_bytes(disk_usage.free),
                "usage_percent": disk_usage.percent,
            }
            system_info["disk"] = disk_info
        except:
            system_info["disk"] = "无法获取磁盘信息"

        # 网络信息（主要接口）
        network_info = get_main_network_interface()
        if network_info:
            system_info["network"] = network_info
        else:
            system_info["network"] = "无法获取网络信息"

        # 进程信息
        system_info["process_count"] = len(psutil.pids())

        # 负载信息（仅适用于类Unix系统）
        if hasattr(os, 'getloadavg'):
            loadavg = os.getloadavg()
            system_info["load_avg"] = {
                "1min": loadavg[0],
                "5min": loadavg[1],
                "15min": loadavg[2],
            }

        # 检查目标进程是否运行
        target_process_info = check_process_running(target_process)
        system_info["target_process"] = target_process_info

        return system_info
    except Exception as e:
        return {"error": f"获取系统信息时出错: {str(e)}"}


def get_system_uptime():
    """获取系统运行时间"""
    try:
        boot_time = psutil.boot_time()
        uptime_seconds = datetime.now().timestamp() - boot_time
        return format_seconds(uptime_seconds)
    except Exception:
        return "未知"


def get_main_network_interface():
    """获取主要网络接口信息"""
    try:
        # 尝试获取非回环接口
        for interface_name, addresses in psutil.net_if_addrs().items():
            if interface_name == 'lo':  # 跳过回环接口
                continue

            for address in addresses:
                # 处理AF_INET可能不存在的情况
                af_inet = getattr(psutil, 'AF_INET', 2)  # 2是socket.AF_INET的常见值

                if address.family == af_inet:
                    return {
                        "name": interface_name,
                        "ip": address.address,
                        "netmask": address.netmask,
                    }
        return None
    except:
        return None


def format_bytes(bytes_value):
    """将字节转换为人类可读的格式"""
    for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
        if bytes_value < 1024.0:
            return f"{bytes_value:.2f} {unit}"
        bytes_value /= 1024.0
    return f"{bytes_value:.2f} PB"


def format_seconds(seconds):
    """将秒转换为人类可读的时间格式"""
    seconds = int(seconds)
    days, seconds = divmod(seconds, 86400)
    hours, seconds = divmod(seconds, 3600)
    minutes, seconds = divmod(seconds, 60)

    if days > 0:
        return f"{days}天 {hours}小时 {minutes}分钟"
    elif hours > 0:
        return f"{hours}小时 {minutes}分钟 {seconds}秒"
    elif minutes > 0:
        return f"{minutes}分钟 {seconds}秒"
    else:
        return f"{seconds}秒"


def check_process_running(target_process="worker.py"):
    """
    检查特定进程是否在运行

    参数:
        target_process: 目标进程的名称或部分命令行参数

    返回:
        dict: 包含进程状态的字典
    """
    process_info = {
        "is_running": False,
        "pid": None,
        "cmdline": None,
        "cpu_percent": None,
        "memory_percent": None,
        "status": None,
        "start_time": None,
        "uptime": None,
    }

    try:
        for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'status', 'create_time']):
            try:
                # 获取进程信息
                cmdline = " ".join(proc.info['cmdline']) if proc.info['cmdline'] else ""
                name = proc.info['name']

                # 检查进程是否匹配目标
                if target_process in cmdline or target_process in name:
                    # 进程匹配，收集详细信息
                    process_info["is_running"] = True
                    process_info["pid"] = proc.info['pid']
                    process_info["cmdline"] = cmdline
                    process_info["status"] = proc.info['status']

                    # 获取CPU和内存使用情况
                    process_info["cpu_percent"] = proc.cpu_percent(interval=0.1)
                    process_info["memory_percent"] = proc.memory_percent()

                    # 计算进程运行时间
                    if proc.info['create_time']:
                        start_time = datetime.fromtimestamp(proc.info['create_time'])
                        process_info["start_time"] = start_time.strftime("%Y-%m-%d %H:%M:%S")

                        uptime_seconds = (datetime.now() - start_time).total_seconds()
                        process_info["uptime"] = format_seconds(uptime_seconds)

                    # 找到目标进程后可以停止遍历
                    break

            except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                # 进程可能在检查期间结束，或没有权限访问
                pass

    except Exception as e:
        process_info["error"] = f"检查进程时出错: {str(e)}"

    return process_info
